# vim:syntax=dockerfile
#------------------------------------------------------------------------------
# Dockerfile for building and testing Solidity Compiler on CI
# Target: Ubuntu ossfuzz Clang variant
# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps
#
# This file is part of solidity.
#
# solidity is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# solidity is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with solidity.  If not, see <http://www.gnu.org/licenses/>
#
# (c) 2016-2021 solidity contributors.
#------------------------------------------------------------------------------
FROM gcr.io/oss-fuzz-base/base-builder AS base
LABEL version="12"

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update; \
	apt-get -qqy install --no-install-recommends \
		automake \
		bison \
		build-essential \
		curl \
		git \
		jq \
		libbz2-dev \
		libc++-18-dev \
		libc++abi-18-dev \
		liblzma-dev \
		libtool \
		lsof \
		m4 \
		mlton \
		ninja-build \
		openjdk-8-jdk \
		pkg-config \
		python3-pip \
		python3-dev \
		software-properties-common \
		sudo \
		texinfo \
		unzip \
		uuid-dev \
		wget \
		zlib1g-dev; \
	pip3 install \
		codecov \
		colorama \
		deepdiff \
		parsec \
		pygments-lexer-solidity \
		pylint \
		requests \
		tabulate;

FROM base AS libraries

# Boost
RUN set -ex; \
	cd /usr/src; \
	wget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2; \
	test "$(sha256sum boost.tar.bz2)" = "6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e  boost.tar.bz2" && \
	tar -xf boost.tar.bz2; \
	rm boost.tar.bz2; \
	cd boost_1_83_0; \
	export CXXFLAGS="$CXXFLAGS -std=c++20 -nostdinc++ -I/usr/local/include/c++/v1 -I/usr/local/include/x86_64-unknown-linux-gnu/c++/v1 -pthread"; \
	export LDFLAGS="$LDFLAGS -stdlib=libc++ -lpthread"; \
	./bootstrap.sh --with-toolset=clang --prefix=/usr; \
	./b2 toolset=clang \
		cxxflags="${CXXFLAGS}" \
		linkflags="${LDFLAGS}" \
		headers; \
	./b2 toolset=clang \
		cxxflags="${CXXFLAGS}" \
		linkflags="${LDFLAGS}" \
		link=static variant=release runtime-link=static \
		system filesystem unit_test_framework program_options \
		install -j $(($(nproc)/2)); \
	rm -rf /usr/src/boost_1_83_0

# Z3
RUN set -ex; \
	z3_version="4.13.3"; \
	z3_archive_name="z3-${z3_version}-x64-glibc-2.35"; \
	wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip" -O /opt/z3.zip; \
	test "$(sha256sum /opt/z3.zip)" = "32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f  /opt/z3.zip"; \
	unzip -j /opt/z3.zip "${z3_archive_name}/bin/z3" -d /usr/bin; \
	rm -f /opt/z3.zip;

# Eldarica
RUN set -ex; \
	apt-get update; \
	apt-get install -qqy openjdk-11-jre; \
	eldarica_version="2.1"; \
	wget "https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip" -O /opt/eld_binaries.zip; \
	test "$(sha256sum /opt/eld_binaries.zip)" = "0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c  /opt/eld_binaries.zip"; \
	unzip /opt/eld_binaries.zip -d /opt; \
	rm -f /opt/eld_binaries.zip;

# CVC5
RUN set -ex; \
	cvc5_version="1.2.0"; \
	cvc5_archive_name="cvc5-Linux-x86_64-static"; \
	wget "https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip" -O /opt/cvc5.zip; \
	test "$(sha256sum /opt/cvc5.zip)" = "d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e  /opt/cvc5.zip"; \
	unzip -j /opt/cvc5.zip "${cvc5_archive_name}/bin/cvc5" -d /usr/bin; \
	rm -f /opt/cvc5.zip;

# OSSFUZZ: libprotobuf-mutator
# Use commit prior to libprotobuf upgrade that broke solidity build
# See https://github.com/google/oss-fuzz/issues/10237
RUN set -ex; \
	git clone https://github.com/google/libprotobuf-mutator.git /usr/src/libprotobuf-mutator; \
	cd /usr/src/libprotobuf-mutator; \
	git reset --hard 212a7be1eb08e7f9c79732d2aab9b2097085d936; \
	mkdir build; \
	cd build; \
	cmake .. -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \
		-DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release \
		-DCMAKE_INSTALL_PREFIX="/usr"; \
	ninja; \
	cp -vpr external.protobuf/bin/* /usr/bin/; \
	cp -vpr external.protobuf/include/* /usr/include/; \
	cp -vpr external.protobuf/lib/* /usr/lib/; \
	ninja install/strip; \
	rm -rf /usr/src/libprotobuf-mutator

# EVMONE
RUN set -ex; \
	cd /usr/src; \
	git clone --branch="v0.16.0" --recurse-submodules https://github.com/ipsilon/evmone.git; \
	cd evmone; \
	mkdir build; \
	cd build; \
	CXX=clang++ cmake .. -G Ninja \
		-DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS="-stdlib=libc++" \
		-DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr"; \
	ninja; \
	ninja install/strip; \
	rm -rf /usr/src/evmone

# gmp
RUN set -ex; \
	# Replace system installed libgmp static library
	# with sanitized version. Do not perform apt
	# remove because it removes mlton as well that
	# we need for building libabicoder
	cd /usr/src/; \
	git clone --depth 1 --branch gmp-6.2.1 https://github.com/gmp-mirror/gmp-6.2 gmp/; \
	rm -r gmp/.git/; \
	test \
		"$(tar --create gmp/ --sort=name --mtime=1970-01-01Z --owner=0 --group=0 --numeric-owner | sha256sum)" = \
		"d606ff6a4ce98692f9920031e85ea8fcf4a65ce1426f6f0048b8794aefed174b  -"; \
	# NOTE: This removes also libgmp.so, which git depends on
	rm -f /usr/lib/x86_64-linux-gnu/libgmp.*; \
	rm -f /usr/include/x86_64-linux-gnu/gmp.h; \
	cd gmp/; \
	autoreconf -i; \
	./configure --prefix=/usr --enable-static=yes --enable-maintainer-mode; \
	make -j; \
	make check; \
	make install; \
	rm -rf /usr/src/gmp/

# libabicoder
RUN set -ex; \
	cd /usr/src; \
	git clone https://github.com/ekpyron/Yul-Isabelle; \
	cd Yul-Isabelle; \
	cd libabicoder; \
	CXX=clang++ CXXFLAGS="-stdlib=libc++ -pthread" make; \
	cp libabicoder.a /usr/lib; \
	cp abicoder.hpp /usr/include; \
	rm -rf /usr/src/Yul-Isabelle

FROM base
COPY --from=libraries /usr/lib /usr/lib
COPY --from=libraries /usr/bin /usr/bin
COPY --from=libraries /usr/include /usr/include
COPY --from=libraries /opt/eldarica /opt/eldarica
ENV PATH="$PATH:/opt/eldarica"
